<template>
  <BasicModal
    v-bind="$attrs"
    :title="t('流程图')"
    :showOkBtn="false"
    :cancelText="t('common.closeText')"
    @register="registerModal"
    @cancel="_closeTip"
    :minHeight="200"
    width="80%"
    :destroyOnClose="true"
  >
    <div class="jeesite-bpm-trace">
      <div class="box-model" v-show="false">
        <div class="box-title">
          <span>{{ t('图例') }} :</span>
          <span style="color: #017501">
            <Icon icon="i-ant-design:check-circle-outlined" style="padding: 5px" />
            {{ t('已完成') }}
          </span>
          <span style="color: #e90606">
            <Icon icon="i-ant-design:clock-circle-outlined" style="padding: 5px" />
            {{ t('进行中') }}
          </span>
          <span style="color: #585858">
            <Icon icon="i-ant-design:minus-circle-outlined" style="padding: 5px" />
            {{ t('未执行') }}
          </span>
        </div>
        <div class="box-tool" v-if="message">{{ message }}</div>
        <div ref="navTree" class="box-tool nav-tree" :data-text-main-process="t('主流程')"></div>
        <div ref="bpmnModel" style="overflow: auto" @click="_closeTip"></div>
      </div>
      <div class="box-timeline">
        <FormGroup>{{ t('流转信息') }}</FormGroup>
        <div class="process-timeline">
          <div class="timeline-connector" v-if="timelineData.length > 0"></div>
          <div 
            v-for="(item, index) in timelineData" 
            :key="index" 
            class="timeline-item"
            :class="{ 'timeline-item-completed': item.status === '已完成', 'timeline-item-active': item.status === '进行中' }"
          >
            <div class="timeline-dot">
              <span class="dot-icon">
                <Icon 
                  :icon="item.status === '已完成' ? 'i-ant-design:check-circle-filled' : 
                         item.status === '进行中' ? 'i-ant-design:clock-circle-filled' : 
                         'i-ant-design:minus-circle-filled'" 
                  :style="{ color: item.status === '已完成' ? '#017501' : item.status === '进行中' ? '#e90606' : '#585858' }" 
                />
              </span>
            </div>
            <div class="timeline-content">
              <div class="timeline-header">
                <div class="timeline-title">
                  {{ item.name || t('未设置环节名') }}
                  <span class="timeline-status" :style="{ color: item.status === '已完成' ? '#017501' : item.status === '进行中' ? '#e90606' : '#585858' }">
                    {{ item.status }}
                  </span>
                </div>
                <div class="timeline-time">
                  <!-- {{ item.createTime }} - {{ item.endTime || '处理中' }} -->
                  创建:{{ item.createTime }}
                </div>
                <div>
                  完成:{{ item.endTime || '处理中' }}
                </div>
              </div>
              <div class="timeline-details">
                <div class="detail-row">
                  <span class="detail-label">{{ t('任务历时') }}:</span>
                  <span class="detail-value">{{ item.durationFormat || '-' }}</span>
                </div>
                <div class="detail-row">
                  <span class="detail-label">{{ t('分配人员') }}:</span>
                  <span class="detail-value">{{ item.assigneeInfo || '-' }}</span>
                </div>
                <div class="detail-row">
                  <span class="detail-label">{{ t('审批意见') }}:</span>
                  <span class="detail-value">{{ item.comment || '-' }}</span>
                </div>
              </div>
              
              <!-- 子时间轴数据展示 -->
              <div v-if="item.children && item.children.length > 0" class="child-timeline-container">
                <div class="child-toggle" @click="toggleChildren(index)">
                  <Icon 
                    :icon="expandedIndex === index ? 'i-ant-design:up-outlined' : 'i-ant-design:down-outlined'" 
                    class="toggle-icon" 
                  />
                  {{ expandedIndex === index ? t('收起') : t('展开') }}
                  <span class="child-count">({{ item.children.length }})</span>
                </div>
                
                <div v-show="expandedIndex === index" class="child-timeline">
                  <div class="child-connector"></div>
                  <div 
                    v-for="(childItem, cIndex) in item.children" 
                    :key="cIndex" 
                    class="child-item"
                  >
                    <div class="child-dot"></div>
                    <div class="child-content">
                      <div class="child-header">
                        <div class="child-title">
                          {{ childItem.notifierName }} - {{ childItem.linkageLevel }}
                        </div>
                        <div class="child-time">{{ childItem.createTime }}</div>
                      </div>
                      <div class="child-details">
                        <div class="child-message">{{ childItem.notifierContent }}</div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </BasicModal>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'JeeSiteBpmRuntimeTrace',
  inheritAttrs: false,
});
</script>

<script lang="ts" setup>
import { defineComponent, ref, defineProps, toRefs, computed, onUnmounted, watch } from 'vue';
import { useI18n } from '/@/hooks/web/useI18n';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicTable, useTable } from '/@/components/Table';
import { FormGroup } from '/@/components/Form';
import { Icon } from '/@/components/Icon';
import {
  bpmTrace,
  bpmProcDefModel,
  bpmProcInsModel,
  bpmProcInsHistoryModel,
  bpmProcInsTrace,
} from '/@/api/bpm';
import { _showProcessDiagram, _closeTip } from './js/displaymodel.js';
import { InFireNotificationData } from '/@/api/management/inFireNotification';

const { t } = useI18n('bpm.button');

const message = ref();
const historyProcInsId = ref('');
const procInsId = ref('');
const procDefId = ref('');
const tableDataSource = ref<Recordable[]>([]);
const traceName = ref('');
const tableName = ref('');
const navTree = ref();
const bpmnModel = ref();
const traceStatus = ref([]);
const ChildrenDataSource = ref();
const expandedIndex = ref(-1); // 当前展开的子流程索引

// 子表列定义
const childTableColumns = ref([
  {
    title: t('通知人'),
    dataIndex: 'notifierName',
    width: 100,
  },
  {
    title: t('通知情况'),
    dataIndex: 'linkageLevel',
    width: 100,
  },
  {
    title: t('通知内容'),
    dataIndex: 'notifierContent',
    width: 100,
  },
  {
    title: t('通知时间'),
    dataIndex: 'createTime',
    width: 100,
  },
]);

const props = defineProps({
  maintainTaskId: {
    type: String,
    default: '',
  },
});

const MaintainceBpmTaskId = ref('');
const TableDataSource2 = ref('');
const endRowName = ref('');

// 计算属性，根据TableDataSource2.value是否存在来决定数据源
const resolvedDataSource = computed(() => {
  return TableDataSource2.value || tableDataSource.value;
});

// 时间轴数据
const timelineData = computed(() => {
  return resolvedDataSource.value.map(item => {
    let statusText = '';
    if (item.status === '2') {
      statusText = '已完成';
    } else if (item.status === '1') {
      statusText = '进行中';
    } else {
      statusText = '未执行';
    }
    
    // 处理子流程数据
    const children = item.children?.map(child => {
      // 根据通知情况判断状态
      let childStatus = '已完成';
      if (child.linkageLevel.includes('待')) {
        childStatus = '进行中';
      }
      
      return {
        ...child,
        status: childStatus
      };
    });
    
    return {
      ...item,
      status: statusText,
      statusColor: item.status === '2' ? '#017501' : item.status === '1' ? '#e90606' : '#585858',
      children: children || []
    };
  });
});

// 切换子流程展开状态
function toggleChildren(index: number) {
  expandedIndex.value = expandedIndex.value === index ? -1 : index;
}

function removeDecimalPart(str) {
  // 查找字符串中最后一个 '秒' 字的位置
  const secondsIndex = str.lastIndexOf('秒');
  if (secondsIndex > -1) {
    // 截取 '秒' 字之前的部分
    const beforeSeconds = str.slice(0, secondsIndex);
    // 找到小数点位置
    const dotIndex = beforeSeconds.lastIndexOf('.');
    if (dotIndex > -1) {
      // 去掉小数点及其后面的内容
      return beforeSeconds.slice(0, dotIndex) + '秒';
    }
  }
  return str;
}

async function showProcessDiagram(bizKey) {
  let data: any = {};
  if (historyProcInsId.value && historyProcInsId.value !== '') {
    data = await bpmProcInsHistoryModel({ id: historyProcInsId.value });
    tableDataSource.value = await bpmProcInsTrace({ id: historyProcInsId.value });
    console.log('tableDataSourceHistory:', tableDataSource.value)
    traceName.value =
      (tableDataSource.value[1]?.procIns?.procDef?.id) ||
      (tableDataSource.value[0]?.procIns?.procDef?.id);
    // 获取数组最后一个元素
    const lastItem =
      tableDataSource.value.length > 0
        ? tableDataSource.value[tableDataSource.value.length - 1]
        : null;
    traceStatus.value = lastItem?.status;
  } else if (procInsId.value && procInsId.value !== '') {
    data = await bpmProcInsModel({ id: procInsId.value });
    tableDataSource.value = await bpmProcInsTrace({ id: procInsId.value });
    console.log('tableDataSource:', tableDataSource.value)
    traceName.value =
      (tableDataSource.value[1]?.procIns?.procDef?.id) ||
      (tableDataSource.value[0]?.procIns?.procDef?.id);
    // 获取数组最后一个元素
    const lastItem =
      tableDataSource.value.length > 0
        ? tableDataSource.value[tableDataSource.value.length - 1]
        : null;
    traceStatus.value = lastItem?.status;
  } else if (procDefId.value && procDefId.value !== '') {
    data = await bpmProcDefModel({ id: procDefId.value });
  }
  if (data.message) {
    message.value = data.message;
    return;
  }
  tableDataSource.value.forEach((item) => {
    if (item.durationFormat) {
      // //console.log(item.durationFormat);
    }
  });
  // 根据traceName的值设置tableName
  if (traceName.value && typeof traceName.value === 'string') {
    if (traceName.value.includes('maintenance_process')) {
      tableName.value = '维保工单流程';
      if (bizKey) {
        const res = await InFireNotificationData({ mainId: bizKey });
        ChildrenDataSource.value = res.list || []; // 赋值响应式变量
        // 手动触发主表 reload（若响应式未自动生效）
        console.log('请求接口InFireNotificationData的结果:', ChildrenDataSource.value);
        const sortedChildren = (res.list || []).sort((a, b) => {
          return new Date(a.createTime).getTime() - new Date(b.createTime).getTime();
        });
        ChildrenDataSource.value = sortedChildren;

        // 直接将数据渲染到所有时间轴的子轴上
        tableDataSource.value.forEach(item => {
          item.children = sortedChildren;
        });
      }
    } else if (traceName.value.includes('supervisor_approval_process')) {
      tableName.value = '监督员审批流程';
    } else if (traceName.value.includes('equipment_fire_warning_process')) {
      tableName.value = '设备火情预警流程';
      // 新增逻辑：请求接口InFireNotificationData
      if (bizKey) {
        const res = await InFireNotificationData({ mainId: bizKey });
        ChildrenDataSource.value = res.list || []; // 赋值响应式变量
        // 手动触发主表 reload（若响应式未自动生效）
        console.log('请求接口InFireNotificationData的结果:', ChildrenDataSource.value);
        const sortedChildren = (res.list || []).sort((a, b) => {
          return new Date(a.createTime).getTime() - new Date(b.createTime).getTime();
        });
        ChildrenDataSource.value = sortedChildren;

        // 筛选子表数据并添加到对应的父表记录中
        const noticeData = ChildrenDataSource.value.filter(item => item.linkageLevel.includes('确认'));
        const disposeData = ChildrenDataSource.value.filter(item => item.linkageLevel.includes('处置'));

        const confirmRow = tableDataSource.value.find(item => item.name === '负责人确认收到预警');
        const disposeRow = tableDataSource.value.find(item => item.name === '负责人处置预警');

        if (confirmRow) {
          confirmRow.children = noticeData;
        }
        if (disposeRow) {
          disposeRow.children = disposeData;
        }
      }
    } else if (traceName.value.includes('Equipment_Failure_Process')) {
      tableName.value = '设备故障流程';
    } else if (traceName.value.includes('Fire_Hazard_Process')) {
      tableName.value = '消防隐患流程';
       // 新增逻辑：请求接口InFireNotificationData
      if (bizKey) {
        const res = await InFireNotificationData({ mainId: bizKey });
        ChildrenDataSource.value = res.list || []; // 赋值响应式变量
        // 手动触发主表 reload（若响应式未自动生效）
        console.log('请求接口InFireNotificationData的结果:', ChildrenDataSource.value);
        const sortedChildren = (res.list || []).sort((a, b) => {
          return new Date(a.createTime).getTime() - new Date(b.createTime).getTime();
        });
        ChildrenDataSource.value = sortedChildren;

        // 直接将数据渲染到所有时间轴的子轴上
        tableDataSource.value.forEach(item => {
          item.children = sortedChildren;
        });
      }
    } else if (traceName.value.includes('leave')) {
      tableName.value = '请假流程';
    } else {
      tableName.value = '';
    }
  }

  // 处理任务历时数据
  tableDataSource.value.forEach((item) => {
    if (item.durationFormat) {
      // 如果字符串包含 '毫秒'，将其替换为 '1秒'
      if (item.durationFormat.includes('毫秒')) {
        item.durationFormat = '1秒';
      } else {
        // 去掉小数点及其后面的内容
        item.durationFormat = removeDecimalPart(item.durationFormat);
      }
    }
  });

  //console.log('tableDataSource:', tableDataSource.value);

  // 在表格第一行增加一行xx流程开始
  const nextRowCreateTime =
    tableDataSource.value.length > 0
      ? tableDataSource.value[0].createTime
      : '';
  const startRow = {
    name: `${tableName.value}开始`,
    createTime: nextRowCreateTime,
    endTime: '',
    durationFormat: '',
    assigneeInfo: '',
    comment: '',
    status: '已完成'
  };
  tableDataSource.value.unshift(startRow);

  // 在表格最后一行增加一行xx流程结束（根据条件判断是否添加）
  if (traceStatus.value === '2') {
    const prevRowEndTime =
      tableDataSource.value.length > 0
        ? tableDataSource.value[tableDataSource.value.length - 1].endTime
        : '';
     endRowName.value = `${tableName.value}结束`;
     console.log('endRowName:', endRowName.value)
    const endRow = {
      name: endRowName.value,
      createTime: '',
      endTime: prevRowEndTime,
      durationFormat: '',
      assigneeInfo: '',
      comment: '',
      status: '已完成'
    };
    tableDataSource.value.push(endRow);
  }
  
  _showProcessDiagram(
    data,
    bpmnModel.value,
    navTree.value,
    tableDataSource.value
  );
}

const [registerModal, { setModalProps }] = useModalInner(
  async (data = {}) => {
    setModalProps({ loading: true });
    if (
      !(data.id && data.id !== '') &&
      data.formKey &&
      data.formKey !== '' &&
      data.bizKey &&
      data.bizKey !== ''
    ) {
      const res = await bpmTrace({ formKey: data.formKey, bizKey: data.bizKey });
      data = res.params || {};
    }
    if (data.status === '1') {
      historyProcInsId.value = '';
      procInsId.value = data.id;
    } else {
      historyProcInsId.value = data.id;
      procInsId.value = '';
    }
    procDefId.value = data.procDef?.id;
    // 确保 tableDataSource.value 有数据
    await showProcessDiagram(data.bizKey);

    if (data.formKey === 'Fire_Hazard_Process' && props.maintainTaskId) {
      endRowName.value = '转维保工单'
      console.log('props.maintainTaskId:', props.maintainTaskId,endRowName.value);
      const newRes = await bpmTrace({
        formKey: 'maintenance_process',
        bizKey: props.maintainTaskId,
      });
      //console.log('二次调用 bpmTrace的id 结果:', newRes.bpmProcIns.id);
      // 不更新data变量，避免影响表格数据
      MaintainceBpmTaskId.value = newRes.bpmProcIns.id;

      if (MaintainceBpmTaskId.value) {
        const secondResult = await bpmProcInsTrace({
          id: MaintainceBpmTaskId.value,
        });

        const processedSecondResult = secondResult.map(item => {
            if (item.durationFormat) {
              item.durationFormat = removeDecimalPart(item.durationFormat); // 调用已有函数
            }
            return item;
          });

        //console.log('二次调用 bpmProcInsTrace的结果:', secondResult);
        // 将 secondResult 数组内对象元素转为 Proxy(Object)
        const proxiedSecondResult = secondResult.map((obj) => {
          return new Proxy(obj, {
            get(target, property) {
              return target[property];
            },
            set(target, property, value) {
              target[property] = value;
              return true;
            },
          });
        });
        // 合并数据
        TableDataSource2.value = [...tableDataSource.value, ...proxiedSecondResult];
        //console.log('tableDataSource2:', TableDataSource2.value);
      }
    }
    setModalProps({ loading: false });
  }
);
</script>

<style scoped lang="less">
.jeesite-bpm-trace {
  position: relative;

  .box-model {
    text-align: center; 

    .box-title {
      padding: 5px;
      margin-bottom: 5px;
      font-weight: bold;

      span {
        padding-right: 5px;
      }
    }

    .box-tool {
      margin-top: 20px;
    }

    .nav-tree a {
      white-space: normal;
      word-break: break-all;
    }

    svg {
      display: inline-block;
    }
  }

  .box-timeline {
    margin-top: 20px;
    
    .process-timeline {
      position: relative;
      margin-left: 40px;
      padding: 10px 0;
      
      .timeline-connector {
        position: absolute;
        top: 0;
        bottom: 0;
        left: -16px;
        width: 2px;
        background-color: #e5e7eb;
        z-index: 1;
      }
      
      .timeline-item {
        position: relative;
        margin-bottom: 25px;
        padding-left: 20px;
        
        .timeline-dot {
          position: absolute;
          left: -22px;
          top: 0;
          width: 24px;
          height: 24px;
          border-radius: 50%;
          background-color: white;
          display: flex;
          align-items: center;
          justify-content: center;
          z-index: 2;
          
          .dot-icon {
            font-size: 18px;
          }
        }
        
        .timeline-content {
          background-color: #ffffff;
          border-radius: 6px;
          padding: 12px 16px;
          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
          transition: all 0.3s ease;
          
          &:hover {
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
          }
          
          .timeline-header {
            display: flex;
            flex-direction: column;
            margin-bottom: 8px;
            
            .timeline-title {
              font-size: 16px;
              font-weight: 500;
              margin-bottom: 4px;
              
              .timeline-status {
                margin-left: 10px;
                font-size: 14px;
                font-weight: normal;
              }
            }
            
            .timeline-time {
              font-size: 13px;
              color: #6b7280;
            }
          }
          
          .timeline-details {
            font-size: 14px;
            color: #4b5563;
            
            .detail-row {
              display: flex;
              margin-bottom: 4px;
              
              .detail-label {
                width: 80px;
                color: #6b7280;
              }
              
              .detail-value {
                flex: 1;
              }
            }
          }
          
          .child-timeline-container {
            margin-top: 15px;
            padding-top: 10px;
            border-top: 1px solid #f3f4f6;
            
            .child-toggle {
              color: #3b82f6;
              cursor: pointer;
              font-size: 13px;
              display: flex;
              align-items: center;
              
              .toggle-icon {
                margin-right: 5px;
              }
              
              .child-count {
                margin-left: 5px;
                color: #6b7280;
                font-size: 12px;
              }
            }
            
            .child-timeline {
              position: relative;
              margin-top: 15px;
              margin-left: 25px;
              padding: 10px 0;
              
              .child-connector {
                position: absolute;
                top: 0;
                bottom: 0;
                left: -14px;
                width: 1px;
                background-color: #e5e7eb;
                z-index: 1;
              }
              
              .child-item {
                position: relative;
                margin-bottom: 15px;
                padding-left: 15px;
                
                .child-dot {
                  position: absolute;
                  left: -17px;
                  top: 5px;
                  width: 10px;
                  height: 10px;
                  border-radius: 50%;
                  background-color: #94a3b8;
                  z-index: 2;
                }
                
                .child-content {
                  background-color: #f8fafc;
                  border-radius: 4px;
                  padding: 8px 12px;
                  font-size: 14px;
                  
                  .child-header {
                    display: flex;
                    justify-content: space-between;
                    margin-bottom: 6px;
                    
                    .child-title {
                      font-weight: 500;
                      color: #334155;
                    }
                    
                    .child-time {
                      font-size: 12px;
                      color: #64748b;
                    }
                  }
                  
                  .child-details {
                    .child-message {
                      color: #475569;
                    }
                  }
                }
              }
            }
          }
        }
      }
      
      .timeline-item-completed {
        .timeline-dot {
          box-shadow: 0 0 0 2px rgba(1, 117, 1, 0.2);
        }
      }
      
      .timeline-item-active {
        .timeline-dot {
          box-shadow: 0 0 0 2px rgba(233, 6, 6, 0.2);
        }
        
        .timeline-content {
          border-left: 2px solid #e90606;
        }
      }
    }
  }
}
</style>